﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace SocketSender
{
    public class Server
    {
        public Server(int port)
        {
            TcpListener = new TcpListener(IPAddress.Any, port);

            Action listenProcess = ListenForClients;

            listenProcess.BeginInvoke(null, null);
        }

        private TcpListener TcpListener { get; set; }

        private void ListenForClients()
        {
            TcpListener.Start();

            while (true)
            {
                TcpClient client = TcpListener.AcceptTcpClient();

                Action<TcpClient> handleClientCommProcess = HandleClientCommunication;

                handleClientCommProcess.BeginInvoke(client, null, null);
            }
        }

        private static void HandleClientCommunication(TcpClient client)
        {
            NetworkStream clientStream = client.GetStream();

            var message = new byte[4096];

            while (true)
            {
                try
                {
                    clientStream.Read(message, 0, 4096);
                }
                catch (Exception)
                {
                    break;
                }

                Console.WriteLine("From Endpoint Address {1} RemoteEndpoint {2} Message Received: '{0}'", ConvertToStringFromBytes(message), client.Client.LocalEndPoint, client.Client.RemoteEndPoint);

                string responseMessage = string.Format("!!!!!!!!!!!!!!!!!!!! SENDING BACK RESPONSE AT {0} !!!!!!!!!!!!!!!!!!!!!!!", DateTime.Now.ToString("HH:mm:ss:fff"));

                byte[] bufferedMessage = Encoding.UTF32.GetBytes(responseMessage);

                clientStream.Write(bufferedMessage, 0, bufferedMessage.Length);

                clientStream.Flush();
            }

            client.Close();
        }

        private static string ConvertToStringFromBytes(byte[] message)
        {
            return Encoding.UTF8.GetString(message).Replace("\0", string.Empty).Trim();
        }
    }
}